package com.booking.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.booking.common.enums.BookingErrorCode;
import com.booking.common.exception.BookingException;
import com.booking.common.utils.ConvertUtils;
import com.booking.controller.model.req.user.LoginReq;
import com.booking.controller.model.req.user.UserCertificationReq;
import com.booking.controller.model.req.user.UserCreateReq;
import com.booking.controller.model.req.user.UserUpdateReq;
import com.booking.controller.model.res.GroupingOrderDetail;
import com.booking.controller.model.res.RoomOrderDetail;
import com.booking.controller.model.res.ServiceOrderDetail;
import com.booking.controller.model.res.UserDetail;
import com.booking.dao.entity.GroupingOrder;
import com.booking.dao.entity.RoomOrder;
import com.booking.dao.entity.ServiceOrder;
import com.booking.dao.entity.UserInfo;
import com.booking.dao.service.GroupingOrderService;
import com.booking.dao.service.RoomOrderService;
import com.booking.dao.service.ServiceOrderService;
import com.booking.dao.service.UserInfoService;
import com.booking.enums.UserTypeEnum;
import com.booking.service.GroupingService;
import com.booking.service.OrderService;
import com.booking.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author Qikai.Lin
 * @date 2023/4/21
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private RoomOrderService roomOrderService;
    @Autowired
    private ServiceOrderService serviceOrderService;
    @Autowired
    private GroupingOrderService groupingOrderService;

    @Autowired
    private OrderService orderService;
    @Autowired
    private GroupingService groupingService;

    private UserInfo getUserInfo(Long userId) {
        UserInfo userInfo = userInfoService.getById(userId);
        if (userInfo == null) {
            throw new BookingException(BookingErrorCode.USER_NOT_EXIST);
        }
        return userInfo;
    }
    @Override
    public UserInfo login(LoginReq request) {
        log.info("用户登陆 request={}", JSON.toJSONString(request));
        UserInfo userInfo = userInfoService.queryByUsername(request.getUsername());
        if (userInfo == null) {
            log.warn("登陆失败：用户不存在");
            throw new BookingException(BookingErrorCode.USER_NOT_EXIST);
        }
        if (!Objects.equals(userInfo.getPassword(), request.getPassword())) {
            log.warn("登陆失败：用户名或密码不正确");
            throw new BookingException(BookingErrorCode.USERNAME_PASSWORD_ERROR);
        }
        userInfo.setUserType(UserTypeEnum.getMsgByType(userInfo.getUserType()));
        log.info("登陆成功 userInfo={}", JSON.toJSONString(userInfo));
        return userInfo;
    }

    @Override
    public void certification(UserCertificationReq request) {
        UserInfo userInfo = userInfoService.queryByUsername(request.getUsername());
        if (userInfo == null) {
            log.warn("认证失败：用户不存在 request={}", JSON.toJSONString(request));
            throw new BookingException(BookingErrorCode.USER_NOT_EXIST);
        }
        userInfo.setName(request.getName());
        userInfo.setCredentialsType(request.getCredentialsType());
        userInfo.setCredentialsNum(request.getCredentialsNum());
        userInfoService.updateById(userInfo);
    }


    @Override
    public UserInfo create(UserCreateReq request) {
        log.info("用户创建 request={}", JSON.toJSONString(request));
        UserInfo userInfo = ConvertUtils.convert(UserInfo.class, request);
        userInfo.setId(IdWorker.getId());
        try {
            userInfoService.save(userInfo);
        } catch (DuplicateKeyException e) {
            log.warn("用户创建失败：用户已存在");
            throw new BookingException(BookingErrorCode.USER_EXIST);
        }
        log.info("用户创建成功！ userInfo={}", JSON.toJSONString(userInfo));
        return userInfo;
    }

    @Override
    public void updateById(UserUpdateReq request) {
        log.info("用户更新 request={}", JSON.toJSONString(request));
        UserInfo userInfo = userInfoService.getById(request.getUserId());
        if (userInfo == null) {
            log.warn("更新失败：用户不存在");
            throw new BookingException(BookingErrorCode.USER_NOT_EXIST);
        }
        UserInfo updateUser = ConvertUtils.convert(UserInfo.class, request);
        ConvertUtils.copy(userInfo, updateUser);
        userInfoService.updateById(userInfo);
        log.info("用户更新成功！");
    }

    @Override
    public UserDetail getDetail(Long userId) {
        log.info("用户查询 userId={}", userId);
        // 查询用户
        UserInfo userInfo = getUserInfo(userId);
        UserDetail userDetail = ConvertUtils.convert(UserDetail.class, userInfo);
        userDetail.setUserType(UserTypeEnum.getMsgByType(userInfo.getUserType()));

        // 查询订单信息
        // 房间订单
        List<RoomOrder> roomOrderList = roomOrderService.getListByVisitorId(userId);
        List<RoomOrderDetail> roomOrderDetailList = new ArrayList<>();
        // 查询每个订单的详情
        roomOrderList.forEach(order -> {
            roomOrderDetailList.add(orderService.getRoomOrderDetail(order.getId()));
        });
        userDetail.setRoomOrderDetailList(roomOrderDetailList);

        // 服务订单
        List<ServiceOrder> serviceOrderList = serviceOrderService.getListByVisitorId(userId);
        List<ServiceOrderDetail> serviceOrderDetailList = new ArrayList<>();
        // 查询每个订单的详情
        serviceOrderList.forEach(order -> {
            serviceOrderDetailList.add(orderService.getServiceOrderDetail(order.getId()));
        });
        userDetail.setServiceOrderDetailList(serviceOrderDetailList);

        // 拼团订单
        List<GroupingOrder> groupingOrderList = groupingOrderService.getListByVisitorId(userId);
        List<GroupingOrderDetail> groupingOrderDetailList = new ArrayList<>();
        // 查询每个订单的详情
        groupingOrderList.forEach(order -> {
            groupingOrderDetailList.add(groupingService.getGroupingOrderDetail(order.getId()));
        });
        userDetail.setGroupingOrderDetailList(groupingOrderDetailList);

        log.info("用户查询成功！ userDetail={}",JSON.toJSONString(userDetail));
        return userDetail;
    }

    @Override
    public void delete(Long userId) {
        log.info("用户删除 userId={}", userId);
        getUserInfo(userId);
        userInfoService.removeById(userId);
        log.info("用户删除成功！");
    }


}
